{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "from openai import OpenAI\n",
    "\n",
    "client = OpenAI(\n",
    "    #api_key=os.getenv(\"DASHSCOPE_API_KEY\"),\n",
    "    api_key=\"ollama\",\n",
    "    base_url=\"http://192.168.20.43:11434/v1\"\n",
    ")\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "[['地区', '住宿费标准(元/天)'], ['北京、上海、广州、深圳', '350'], ['各省省会城市及直辖市(天津、重庆) 及计划单列市(大连、青岛、宁波、厦 门 )', '250'], ['其他城市', '200']]\n"
     ]
    }
   ],
   "source": [
    "from docx import Document\n",
    "\n",
    "def read_docx_tables(file_path):\n",
    "    document = Document(file_path)\n",
    "    tables_all = []\n",
    "\n",
    "    # 遍历文档中的所有表格\n",
    "    for table in document.tables:    \n",
    "        table_data = []\n",
    "        # 遍历表格的每一行,把每一行作为一个数组加入到table_data中，构成一个元组。\n",
    "        for row in table.rows:\n",
    "            row_data = [cell.text.strip() for cell in row.cells]\n",
    "            table_data.append(row_data)\n",
    "        tables_all.append(table_data)\n",
    "        #print(tables_all)\n",
    "    return tables_all\n",
    "\n",
    "file_path = 'Data/财务报销办法6.0.docx'\n",
    "tables = read_docx_tables(file_path)\n",
    "print()\n",
    "print(tables[4])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def llm_summary_table(query):\n",
    "    prompt = \"\"\"\n",
    "    # OBJECTIVE #\n",
    "    任务：分析用户给出的表格，并详细描述其内容，以便让没看过表格的人也能清楚地知道表格中的内容。\n",
    "    你需要遵循以下要求：\n",
    "    1.明确标题和表头：在描述之前，首先需要明确表格的标题和每列的表头。这些信息可以帮助读者快速理解表格的主要内容和结构。\n",
    "    2.详细解释各列和行：对于每一列和行的数据，提供详细的解释。例如，如果某列是“销售额”，则说明它代表的是某个时间段内的总销售额，并且单位是什么（如美元、欧元等）\n",
    "    3.突出重要数据：强调关键数据点，使读者能够迅速识别出重要的信息。\n",
    "    4.图例（Caption）：图例为读者提供了图表的简短描述，包括图表的标题和必要的解释，帮助读者理解图表所展示的信息。\n",
    "    \n",
    "    # TONE #\n",
    "    有条理、精炼、准确的语言。\n",
    "    \"\"\"\n",
    "    completion = client.chat.completions.create(\n",
    "        model=\"qwen2-7b-instruct\",\n",
    "        messages=[{'role': 'system', 'content': prompt},\n",
    "                  {'role': 'user', 'content': query}],\n",
    "        )\n",
    "    return completion.choices[0].message.content\n",
    "\n",
    "# 测试\n",
    "# text = str(tables[4])               #只取doc中第五张表格作为测试\n",
    "# text_before = \"2.2.3  住宿标准：\"    #手动补了一下表格前面的内容，这个有助于让大模型了解表格是关于什么的。实际实现要通过代码。\n",
    "# summary_text = llm_summary_table(text_before+text) #注意这里会拼成user_query，usery_query会和system_prompt一起扔给大模型。\n",
    "# print(summary_text)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## V2 表格的简短摘要\n",
    "\n",
    "以上版本太啰嗦，语义命中率不高\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "表2.2  出油、集油、输油管道分类 \n",
      " 表2.2和表2.3分别列出了出油、集油、输油和供水、注入管道根据压力和直径分类为Ⅰ、Ⅱ、Ⅲ类的标准，以及管道按风险等级划分。\n"
     ]
    }
   ],
   "source": [
    "def llm_summary_table_short(context_str):\n",
    "    system_prompt = f\"\"\"\n",
    "    \"\"\"\n",
    "    query = f\"\"\"\n",
    "    ## OBJECTIVE \n",
    "    - 提供一个简洁的句子摘要，概括CONTEXT的主要信息，\n",
    "    - 确保摘要准确捕捉到语义信息、关键概念和术语。\n",
    "\n",
    "    ## CONTEXT \n",
    "    {context_str}\\\n",
    "\n",
    "    ## 约束 \n",
    "    - 不要包括context中没有的内容. \\\n",
    "    - 摘要应控制在60字以内.\\\n",
    "    - 无需前言和总结.\\\n",
    "    - Reply in Chinese.\\\n",
    "    \"\"\"\n",
    "    completion = client.chat.completions.create(\n",
    "        model=\"qwen2.5:14b\",\n",
    "        messages=[{'role': 'system', 'content': system_prompt},\n",
    "                  {'role': 'user', 'content': query}],\n",
    "        )\n",
    "    return completion.choices[0].message.content\n",
    "\n",
    "# 测试\n",
    "# table_str = str(tables[4])               #取doc中第五张表格作为测试\n",
    "table_str = \"\"\"\n",
    "\\n\\n<table><tr><td></td><td>P≥6.3</td><td>4≤P<6.3</td><td>2.5＜P＜4</td><td>P≤2.5</td></tr><tr><td>DN≥250</td><td>Ⅰ类管道</td><td>Ⅰ类管道</td><td>Ⅱ类管道</td><td>Ⅱ类管道</td></tr><tr><td>100≤DN<250</td><td>Ⅰ类管道</td><td>Ⅱ类管道</td><td>Ⅱ类管道</td><td>Ⅱ类管道</td></tr><tr><td>DN<100</td><td>Ⅱ类管道</td><td>Ⅱ类管道</td><td>Ⅱ类管道</td><td>Ⅲ类管道</td></tr></table>\\n注：1.P，最近3年的最高运行压力，MPa；DN，公称直径，mm；\\n2.输油管道按Ⅰ类管道处理；液化气、轻烃管道，类别上升一级；Ⅰ、Ⅱ管道长度小于3km的，类别下降一级；Ⅲ类管道中的高后果区管道，类别上升一级。\\n表2.3  供水、注入管道分类\\n<table><tr><td></td><td>P≥16</td><td>6.3≤P＜16</td><td>2.5＜P＜6.3</td><td>P≤2.5</td></tr><tr><td>DN≥200</td><td>Ⅱ类管道</td><td>Ⅱ类管道</td><td>Ⅲ类管道</td><td>Ⅲ类管道</td></tr><tr><td>DN<200</td><td>Ⅱ类管道</td><td>Ⅲ类管道</td><td>Ⅲ类管道</td><td>Ⅲ类管道</td></tr></table>\\n注：P，最近3年的最高运行压力，MPa；DN，公称直径，mm。\\n管道按照风险大小可划分为高风险级管道、中风险级管道和低风险级管道三个等级。风险等级示意图见图2.1。\\n\n",
    "\"\"\"\n",
    "table_head = \"表2.2  出油、集油、输油管道分类\"    #手动补了一下表格前面的内容，这个有助于让大模型了解表格是关于什么的。实际实现要通过代码。\n",
    "summary_text = llm_summary_table_short(table_head+table_str) #注意这里会拼成user_query，usery_query会和system_prompt一起扔给大模型。\n",
    "print(f\"{table_head} \\n {summary_text}\")\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
